package service

import (
	"reflect"
	"remoteGo/remote/io"
	"remoteGo/remote/lvs"
)

type Master struct {
	lvs lvs.LVS
	//socket io.Socket
}

func NewMaster(lvs lvs.LVS) *Master {
	return &Master{
		lvs: lvs,
	}
}

func (m *Master) NewInvokeProcess(id FuncID, args []any) *InvokeProcess {
	i := &InvokeProcess{
		node: m.lvs.GetNode(),
		id:   id,
	}
	socket, err := i.node.NewSocket()
	if err != nil {
		//TODO: handle error
		panic(err)
	}
	i.socket = socket

	i.wrapArgs(args)

	//for _, x := range i.receive {
	//	x.Listen()
	//}
	return i
}

// InvokeProcess 调用过程
type InvokeProcess struct {
	id          FuncID
	wrappedArgs []any
	receive     []*ChanRecvProxy
	node        lvs.Node
	socket      io.Socket
	master      Master
}

func (p *InvokeProcess) wrapArgs(args []any) {
	p.wrappedArgs = make([]interface{}, len(args))
	for i, x := range args {
		t := reflect.TypeOf(x)
		if t.Kind() == reflect.Chan {
			proxy := ChanProxy{
				Cid: ChanID(len(p.receive)),
			}
			p.wrappedArgs[i] = proxy
			recvProxy := &ChanRecvProxy{
				cp:      proxy,
				chanVal: reflect.ValueOf(x),
			}
			p.receive = append(p.receive, recvProxy)
		} else {
			p.wrappedArgs[i] = x
		}
	}
}

//func (p *InvokeProcess) stopChanRecv() {
//	for _, x := range p.receive {
//		x.Stop()
//	}
//}

func (p *InvokeProcess) Invoke() {
	req := Invoke{
		Uid:  p.id,
		Args: p.wrappedArgs,
	}
	err := p.socket.Send(req)
	if err != nil {
		panic(err)
	}
	go func() {
		for {
			//TODO: stop
			var r ChanMessage
			//fmt.Println("wait")
			err := p.socket.Recv(&r)
			//fmt.Println(r)
			if err != nil {
				panic(err)
			}
			p.receive[r.Proxy.Cid].chanVal.Send(reflect.ValueOf(r.Message))
		}
	}()
}
